

<template>
	<div class="app-container" v-loading="loading">
		
		<div class="search-container  app_ny">
			<div class="div2" style="position: relative">
				<el-row :gutter="12" style="width: 100%">
					<el-col :span="3">
						<el-input v-model="queryParams.keywords" placeholder="请输入角色名称" clearable
							@keyup.enter="handleQuery" />
					</el-col>
				
					<el-col :span="6" >
						<el-button  :loading="loading"  type="primary" @click="handleQuery"><template
							#icon><i-ep-search /></template>查询</el-button>
					</el-col>
				</el-row>
				<FilterColumn
				 class="filtBox"
				 @handleRefresh="resetQuery()"
				:strtype="strtype" :columns="false"></FilterColumn>
			</div>	
		</div>
		
		

		<el-card shadow="never">
			
			<div class="action-row">
				<el-button type="primary" @click="openDialog()" plain>
					<template #icon><i-ep-plus /></template>新增</el-button>
			</div>
			

			<el-table v-loading="loading" :data="roleList" :tree-props="{ children: 'children',hasChildren: 'hasChildren',}" row-key="id" default-expand-all border size="small" @row-click="onRowClick">
				<el-table-column type="index" label="序号" align="center" width="80" />
				<el-table-column label="角色名称" min-width="200">
					<template #default="scope">
						{{ scope.row.role_name }}
					</template>
				</el-table-column>

				<el-table-column label="数据权限" align="center" width="180">
					<template #default="scope">
						<el-tag v-if="scope.row.data_scope == 0">全部数据</el-tag>
						<el-tag v-if="scope.row.data_scope == 1" type="success">部门及子部门数据</el-tag>
						<el-tag v-if="scope.row.data_scope == 2" type="danger">本部门数据</el-tag>
						<el-tag v-if="scope.row.data_scope == 3" type="info">本人数据</el-tag>

					</template>
				</el-table-column>

				<el-table-column label="状态" align="center" width="80">
					<template #default="scope">
						<el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
						<el-tag v-else type="info">停用</el-tag>
					</template>
				</el-table-column>
				<el-table-column label="排序" align="center" width="80" prop="sort" />

				<el-table-column fixed="right" align="center" label="操作" width="220">
					<template #default="scope">

						<el-button v-hasPerm="['RolesRules']" type="success" size="small" link
							@click="openMenuDialog(scope.row)">
							<template #icon><i-ep-position /></template>
							分配权限
						</el-button>
						<el-button v-hasPerm="['Roles/update']" type="primary" size="small" link
							@click="openDialog(scope.row.id)">
							<template #icon><i-ep-edit /></template>编辑
						</el-button>
						<el-button v-hasPerm="['Roles/delete']" type="danger" size="small" link
							@click="handleDelete(scope.row.id)">
							<template #icon><i-ep-delete /></template>删除
						</el-button>

					</template>
				</el-table-column>
			</el-table>
		</el-card>

		<!-- 角色表单弹窗 -->
		<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" @close="closeDialog">
			<el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="100px">

				<el-form-item label="父级角色" prop="pid">
					<el-tree-select v-model="formData.pid" placeholder="选择父级角色" :data="roleOptions" :props="{
              label: 'role_name',
              children: 'children',
              value: 'id',
            }" :default-expand-all="true" filterable check-strictly :render-after-expand="false" />
				</el-form-item>

				<el-form-item label="角色名称" prop="role_name">
					<el-input v-model="formData.role_name" placeholder="请输入角色名称" />
				</el-form-item>

				<el-form-item label="数据权限" prop="data_scope">
					<el-select v-model="formData.data_scope">
						<el-option :key="0" label="全部数据" :value="0" />
						<el-option :key="1" label="部门及子部门数据" :value="1" />
						<el-option :key="2" label="本部门数据" :value="2" />
						<el-option :key="3" label="本人数据" :value="3" />
					</el-select>
				</el-form-item>

				<el-form-item label="状态" prop="status">
					<el-radio-group v-model="formData.status">
						<el-radio :label="1">正常</el-radio>
						<el-radio :label="0">停用</el-radio>
					</el-radio-group>
				</el-form-item>

				<el-form-item label="排序" prop="sort">
					<el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
				</el-form-item>
			</el-form>

			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" @click="handleSubmit">确 定</el-button>
					<el-button @click="closeDialog">取 消</el-button>
				</div>
			</template>
		</el-dialog>

		<!-- 分配菜单弹窗  -->
		<el-dialog v-model="menuDialogVisible" :title="'【' + checkedRole.role_name + '】权限分配'" width="800px">
			<el-scrollbar v-loading="loading" max-height="600px">
				<el-tree ref="menuRef" node-key="id" show-checkbox :props="{
              value: 'id',
              label: 'name',
              children: 'children',
            }" :data="menuList" :default-expand-all="true">
					<template #default="{ data }">
						{{ data.name }}
					</template>
				</el-tree>
			</el-scrollbar>

			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" @click="handleRoleMenuSubmit">确 定</el-button>
					<el-button @click="menuDialogVisible = false">取 消</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
	defineOptions({
		name: "Role",
		inheritAttrs: false,
	});

	import {
		getRolePage,
		updateRole,
		getRoleForm,
		addRole,
		deleteRoles,
		updateRoleMenus,
		listRoleOptions,
	} from "@/api/role";
	import { listMenuOptions } from "@/api/menu";

	import { RoleVO, RoleForm, RoleQuery } from "@/api/role/types";
	
	
	const strtype = ref('systemRoleIndex'); //数据
	const queryFormRef = ref(ElForm);
	const roleFormRef = ref(ElForm);
	const menuRef = ref(ElTree);

	const loading = ref(false);
	const ids = ref<number[]>([]);

	const queryParams = reactive<RoleQuery>({});

	const roleList = ref<RoleVO[]>();

	const dialog = reactive<DialogOption>({
		visible: false,
	});

	const formData = reactive<RoleForm>({
		sort: 50,
		status: 1,
		pid: undefined,
		role_name: "",
		data_scope: undefined,
		rules: [],
	});

	const roleOptions = ref<any>([]);

	const rules = reactive({
		pid: [{ required: true, message: "请选择父级角色", trigger: "blur" }],
		role_name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
		data_scope: [{ required: true, message: "请选择数据权限", trigger: "blur" }],
		status: [{ required: true, message: "请选择状态", trigger: "blur" }],
	});

	// 选择表格的行角色ID
	const selectedRowRoleId = ref<number | undefined>();

	const menuDialogVisible = ref(false);

	const menuList = ref<OptionType[]>([]);

	interface CheckedRole {
		id ?: number;
		role_name ?: string;
		pid ?: number;
		sort ?: number;
		data_scope ?: number;
		rules ?: [];
	}
	let checkedRole : CheckedRole = reactive({});

	/**
	 * 查询
	 */
	function handleQuery() {
		loading.value = true;
		getRolePage(queryParams)
			.then(({ data }) => {
				roleList.value = data;
			})
			.finally(() => {
				loading.value = false;
			});
	}
	/**
	 * 重置查询
	 */
	function resetQuery() {
		queryFormRef.value.resetFields();
		handleQuery();
	}

	/**
	 * 行点击事件
	 */
	function onRowClick(row : RoleVO) {
		selectedRowRoleId.value = row.id;
	}

	/**
	 * 打开角色表单弹窗
	 *
	 * @param roleId
	 */
	function openDialog(roleId ?: number) {
		listRoleOptions()
			.then(({ data }) => {
				roleOptions.value = [{ id: 0, role_name: "顶级角色", children: data }];
			})
			.then(() => {
				dialog.visible = true;
				if (roleId) {
					dialog.title = "修改角色";
					getRoleForm(roleId).then(({ data }) => {
						Object.assign(formData, data);
					});
				} else {
					dialog.title = "新增角色";
				}
			});
	}

	/**
	 * 角色表单提交
	 */
	function handleSubmit() {
		loading.value = true;
		roleFormRef.value.validate((valid : any) => {
			if (valid) {
				const roleId = formData.id;
				if (roleId) {
					updateRole(roleId, formData)
						.then(() => {
							ElMessage.success("修改成功");
							closeDialog();
							resetQuery();
						})
						.finally(() => (loading.value = false));
				} else {
					addRole(formData)
						.then(() => {
							ElMessage.success("新增成功");
							closeDialog();
							resetQuery();
						})
						.finally(() => (loading.value = false));
				}
			}
		});
	}

	/**
	 * 关闭弹窗
	 */
	function closeDialog() {
		dialog.visible = false;
		resetForm();
	}

	/**
	 * 重置表单
	 */
	function resetForm() {
		roleFormRef.value.resetFields();
		roleFormRef.value.clearValidate();

		formData.id = undefined;
		formData.sort = 50;
		formData.status = 1;
	}

	/**
	 * 删除
	 */
	function handleDelete(roleId ?: number) {
		const roleIds = [roleId || ids.value].join(",");
		if (!roleIds) {
			ElMessage.warning("请勾选删除项");
			return;
		}

		ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
			confirmButtonText: "确定",
			cancelButtonText: "取消",
			type: "warning",
		}).then(() => {
			loading.value = true;
			deleteRoles(roleIds)
				.then(() => {
					ElMessage.success("删除成功");
					resetQuery();
				})
				.finally(() => (loading.value = false));
		});
	}

	/**
	 * 打开分配菜单弹窗
	 */
	function openMenuDialog(row : RoleVO) {
		const roleId = row.id;
		if (roleId) {
			checkedRole = {
				id: roleId,
				role_name: row.role_name,
				pid: row.pid,
				rules: row.rules,
				data_scope: row.data_scope,
			};
			menuDialogVisible.value = true;
			loading.value = true;

			// 获取所有的菜单
			listMenuOptions().then((response) => {
				menuList.value = response.data;
				// 回显角色已拥有的菜单
				const checkedMenuIds = row.rules;
				console.log("勾选权限", checkedMenuIds);
				if (checkedMenuIds) {
					console.log(row.rules)
					//menuRef.value.setCheckedKeys(row.rules, true)
					// checkedMenuIds.forEach((menuId) =>
					//   menuRef.value.setChecked(menuId, true, false)
					// );
					setTimeout(function () {
						checkedMenuIds.forEach((menuId) =>
							menuRef.value.setChecked(menuId, true, false)
						);
					}, 100);

				}
				loading.value = false;
			});
		}
	}

	/**
	 * 角色分配菜单提交
	 */
	function handleRoleMenuSubmit() {
		const roleId = checkedRole.id;
		if (roleId) {
			const checkedMenuIds : number[] = menuRef.value
				.getCheckedNodes(false, true)
				.map((node : any) => node.id);
			loading.value = true;
			updateRoleMenus(roleId, checkedMenuIds)
				.then((res) => {
					ElMessage.success("分配权限成功");
					menuDialogVisible.value = false;
					resetQuery();
				})
				.finally(() => {
					loading.value = false;
				});
		}
	}

	onMounted(() => {
		handleQuery();
	});
</script>
